let target, show_token = (
	let target = ref "" in
	let show_token = ref false in
	let args = Stream.of_list (List.tl (Array.to_list Sys.argv)) in
	while Stream.peek args <> None do
		match Stream.next args with
		| "-v" ->
			show_token := true
		| "-w" ->
			Parser.debug := true
		| _ as s when s.[0] = '-' ->
			raise (Failure ("Invalid option: " ^ s))
		| _ as path ->
			target := path
	done;
	!target, !show_token
);;

let pp_position f (_, _, line, column) = (
	Format.pp_print_int f line;
	Format.pp_print_string f ":";
	Format.pp_print_int f column
);;

let test filename = (
	let print_error ((pf, pl), error) = (
		let f = Format.str_formatter in
		pp_position f pf;
		if pf <> pl then (
			Format.pp_print_string f "-";
			pp_position f pl
		);
		Format.pp_print_space f ();
		Parser.pp_error (Lexical.Token.pp ~paren:true ~quali:false) f error;
		Format.pp_print_cut f ();
		print_string (Format.flush_str_formatter ());
	) in
	let f = if filename <> "" then open_in_bin filename else stdin in
	let input_stream = Stream.of_channel f in
	let s = Scanner.create ~tab:3 ~filename:"post.pas" in
	let p = Parser.create () in
	let rec loop s p = (
		if Scanner.is_empty s then (
			let c = try Stream.next input_stream with Stream.Failure -> '\x1a' in
			let s = Scanner.post c s in
			loop s p
		) else (
			let s, t, pos = Scanner.next s in
			if show_token then (
				let f = Format.std_formatter in
				let (pf, pl) = pos in
				pp_position f pf;
				if pf <> pl then (
					Format.pp_print_string f "-";
					pp_position f pl
				);
				Format.pp_print_space f ();
				Lexical.Token.pp ~quali:false ~paren:false Format.std_formatter t;
				Format.pp_print_flush Format.std_formatter ();
				print_newline ()
			);
			let p = Parser.post pos t p in
			if t <> Lexical.EOF then loop s p else p
		)
	) in 
	let p = loop s p in
	if filename <> "" then close_in f;
	let errors = List.rev (Parser.errors p) in
	List.iter print_error errors
);;

test target;;
